package com.mzj.saas.mservice.roles.service;

import cn.hutool.core.util.ObjectUtil;
import com.mzj.saas.commons.Constant;
import com.mzj.saas.commons.ResultBean;
import com.mzj.saas.commons.StatusCode;
import com.mzj.saas.commons.util.StringUtils;
import com.mzj.saas.commons.vo.redis.TokenRedisVo;
import com.mzj.saas.mservice.department.entity.Department;
import com.mzj.saas.mservice.department.repository.DepartmentRepository;
import com.mzj.saas.mservice.roles.entity.Role;
import com.mzj.saas.mservice.roles.entity.RolePermission;
import com.mzj.saas.mservice.roles.entity.UserRoleRef;
import com.mzj.saas.mservice.roles.mapper.RoleRowMapper;
import com.mzj.saas.mservice.roles.repository.RolePermissionRepository;
import com.mzj.saas.mservice.roles.repository.RoleRepository;
import com.mzj.saas.mservice.roles.repository.UserRoleRefRepository;
import com.mzj.saas.mservice.roles.vo.RolePeopleVO;
import com.mzj.saas.mservice.roles.vo.RoleVO;
import com.mzj.saas.mservice.roles.vo.UserRoleRefVO;
import com.mzj.saas.mservice.sys.entity.Permission;
import com.mzj.saas.mservice.sys.entity.User;
import com.mzj.saas.mservice.sys.repository.PermissionRepository;
import com.mzj.saas.mservice.sys.repository.UserRepository;
import com.mzj.saas.mservice.sys.utils.CheckUtil;
import com.mzj.saas.mservice.sys.utils.SqlUtils;
import com.mzj.saas.mservice.sys.vo.ParamVO;
import com.mzj.saas.redis.RedisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestHeader;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Transactional
public class RolesService {
    private static final Logger LOG = LoggerFactory.getLogger(RolesService.class);

    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private RedisService redisService;
    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private UserRoleRefRepository userRoleRefRepository;
    @Autowired
    private PermissionRepository permissionRepository;
    @Autowired
    private RolePermissionRepository rolePermissionRepository;
    @Autowired
    private DepartmentRepository departmentRepository;

    /*
     *新增角色组
     */
    public ResultBean<Object> addRoleGroup(String accessToken, RoleVO roleVO) {
        LOG.info("RolesService addRoleGroup accessToken={},roleVO={}", accessToken, roleVO);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (roleVO == null) {
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                return result;
            }
            if (StringUtils.isBlank(roleVO.getName())) {
                return ResultBean.failedResultWithMsg("角色组名称不能为空");
            }
            Optional<Department> existDepartment = departmentRepository.findById(tokenRedisVo.getEnterpriseId());
            if (existDepartment == null) {
                return ResultBean.failedResultWithMsg("企业信息有误");
            }
            roleVO.setOrgId(tokenRedisVo.getEnterpriseId());
            roleVO.setProperty(1);
            roleVO.setParentId((long) 0);
            roleVO.setPropertyType(0);
            Role existRoleGroup = roleRepository.findByNameAndOrgId(roleVO.getName(), tokenRedisVo.getEnterpriseId());
            if (existRoleGroup == null) {
                Role role = new Role();
                BeanUtils.copyProperties(roleVO, role);
                Role save = roleRepository.save(role);
                if (save != null) {

                    UserRoleRef existUserRole = userRoleRefRepository.findByUserIdAndRoleId(tokenRedisVo.getId(), save.getId());
                    if (existUserRole == null) {
                        UserRoleRef userRoleRef = new UserRoleRef();
                        userRoleRef.setRoleId(save.getId());
                        userRoleRef.setUserId(tokenRedisVo.getId());
                        userRoleRefRepository.save(userRoleRef);
                    }
                }
            }
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     *新增角色
     */
    public ResultBean<Object> addRole(String accessToken, RoleVO roleVo) {
        LOG.info("RolesService addRole accessToken={},roleVo={}", accessToken, roleVo);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (roleVo == null) {
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                return result;
            }
            if (roleVo.getParentId() == null) {
                return ResultBean.failedResultWithMsg("角色组Id不能为空");
            }
            if (StringUtils.isBlank(roleVo.getName())) {
                return ResultBean.failedResultWithMsg("角色名称不能为空");
            }

            Role findRole = roleRepository.findByNameAndPropertyAndOrgId(roleVo.getName(), 2, tokenRedisVo.getEnterpriseId());
            if (ObjectUtil.isNotEmpty(findRole)) {
                return ResultBean.failedResultWithMsg("该角色已存在");
            }

            roleVo.setProperty(2);
            roleVo.setOrgId(tokenRedisVo.getEnterpriseId());
            Optional<Role> roleGroupOptional = roleRepository.findById(roleVo.getParentId());
            if (!roleGroupOptional.isPresent()) {
                return ResultBean.failedResultWithMsg("角色组信息不存在或是已删除");
            } else {
                Role role = roleGroupOptional.get();
                if (role.getPropertyType() == 1) {
                    roleVo.setType(2);
                } else {
                    roleVo.setType(0);
                }
            }

            Role role = new Role();
            BeanUtils.copyProperties(roleVo, role);
            Role save = roleRepository.save(role);

            if (save != null) {
                UserRoleRef existUserRoleGroup = userRoleRefRepository.findByUserIdAndRoleId(tokenRedisVo.getId(), roleVo.getParentId());
                if (existUserRoleGroup == null) {
                    //增加角色组关系
                    UserRoleRef userRoleRef = new UserRoleRef();
                    userRoleRef.setUserId(tokenRedisVo.getId());
                    userRoleRef.setRoleId(roleVo.getParentId());
                    userRoleRefRepository.save(userRoleRef);
                }

                UserRoleRef existUserRole = userRoleRefRepository.findByUserIdAndRoleId(tokenRedisVo.getId(), save.getId());
                if (existUserRole == null) {
                    UserRoleRef roleRef = new UserRoleRef();
                    roleRef.setUserId(tokenRedisVo.getId());
                    roleRef.setRoleId(save.getId());
                    userRoleRefRepository.save(roleRef);
                }
            }
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     *修改角色组或角色名称
     */
    public ResultBean<Object> updateRoleName(String accessToken, RoleVO roleVO) {
        LOG.info("RolesService updateRoleName accessToken={},roleVO={}", accessToken, roleVO);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (roleVO == null) {
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                return result;
            }
            CheckUtil checkUtil = new CheckUtil();
            checkUtil.checkValues(roleVO);
            if (checkUtil.isNull()) {
                return ResultBean.failedResultOfParamWithMsg(checkUtil.getMessage());
            }
            if (roleVO.getId() == null) {
                return ResultBean.failedResultWithMsg("编号不能为空！");
            }
            Optional<Role> roleOptional = roleRepository.findById(roleVO.getId());
            if (roleOptional == null) {
                return ResultBean.failedResultWithMsg("信息有误");
            }
            Role role = roleOptional.get();
            Role existRoleGroup = roleRepository.findByNameAndPropertyAndOrgId(roleVO.getName(), role.getProperty(), tokenRedisVo.getEnterpriseId());
            if (existRoleGroup != null && existRoleGroup.getId() != roleVO.getId()) {
                return ResultBean.failedResultWithMsg("名称已被使用,请更换名称");
            }
            role.setName(roleVO.getName());
            roleRepository.save(role);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     *根据角色组Id显示角色列表
     */
    public ResultBean<Object> roleListByRoleGroup(String accessToken, Long roleId) {
        LOG.info("RolesService roleListByRoleGroup accessToken={},roleId={}", accessToken, roleId);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (roleId == null) {
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                return result;
            }
            Role existRoleGroup = roleRepository.findByIdAndProperty(roleId, 1);
            if (existRoleGroup == null) {
                return ResultBean.failedResultWithMsg("角色组不存在或是已删除！");
            }
            List<Role> childRole = roleRepository.findByParentId(roleId);
            result.setResultData(childRole);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     *更换主管理员
     */
    public ResultBean<Object> changeMainManager(String accessToken, Long mainRoleId, String userId) {
        LOG.info("RolesService changeMainManager accessToken={},mainRoleId={},userId={}", accessToken, mainRoleId, userId);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (mainRoleId == null || userId == null) {
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                return result;
            }
            if (tokenRedisVo.getMasterStatus() != 1) {
                return ResultBean.failedResultWithMsg("当前用户不具有更换主管理员的权限");
            }

            User user = userRepository.findById(userId);
            if (user == null) {
                return ResultBean.failedResultWithMsg("用户不存在或是已删除");
            }

            Optional<Role> roleOptional = roleRepository.findById(mainRoleId);
            if (roleOptional == null) {
                return ResultBean.failedResultWithMsg("主管理员角色不存在");
            }
            Role role = roleOptional.get();

            List<UserRoleRef> userRoleRefList = userRoleRefRepository.findByRoleId(mainRoleId);
            if (userRoleRefList.isEmpty()) {
                return ResultBean.failedResultWithMsg("主管理员角色数据有误");
            }
            UserRoleRef existUserRoleRef = userRoleRefList.get(0);

            userRoleRefRepository.deleteByUserId(tokenRedisVo.getId());

            UserRoleRef groupUserRoleRef = userRoleRefRepository.findByUserIdAndRoleId(userId, role.getId());
            if (groupUserRoleRef == null) {
                UserRoleRef groupUserRole = new UserRoleRef();
                groupUserRole.setUserId(userId);
                groupUserRole.setRoleId(role.getId());
                userRoleRefRepository.save(groupUserRole);
            }

            existUserRoleRef.setUserId(userId);
            UserRoleRef save = userRoleRefRepository.save(existUserRoleRef);

            result.setResultData(save);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     *查询当前用户所具有权限的角色组
     */
    public ResultBean<Object> userRoleGroupList(String accessToken, String roleName) {
        LOG.info("RolesService userRoleGroupList accessToken={},roleName={}", accessToken, roleName);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            User user = userRepository.findById(tokenRedisVo.getId());
            if (user == null) {
                return ResultBean.failedResultWithMsg("用户信息不存在或已删除！");
            }
            Optional<Department> existDepartment = departmentRepository.findById(tokenRedisVo.getEnterpriseId());
            if (existDepartment == null) {
                return ResultBean.failedResultWithMsg("企业信息不存在或已删除！");
            }
            if (tokenRedisVo.getMasterStatus() != 1) {
                //优化，不要查询出默认角色
                //String sql = "SELECT r.`id`,r.`org_id`,r.`parent_id`,r.`name`,r.`code`,r.`property`,r.`type`,r.`property_type`,r.`description` FROM `saas_role` r INNER JOIN `saas_user_role_ref` ur ON r.id=ur.role_id WHERE ur.user_id=? AND r.`org_id`=? AND r.`property`=1 \n";
                String sql = "SELECT r.`id`,r.`org_id`,r.`parent_id`,r.`name`,r.`code`,r.`property`,r.`type`,r.`property_type`,r.`description` FROM `saas_role` r WHERE r.`org_id`=? AND r.`property`=1 and r.property_type = 0\n";
                List<Object> args = new ArrayList<>();
                // args.add(user.getId());
                args.add(tokenRedisVo.getEnterpriseId());
                if (!StringUtils.isBlank(roleName)) {
                    sql += "  AND NAME like  ? ";
                    Role existRole = roleRepository.findByOrgIdAndPropertyAndName(tokenRedisVo.getEnterpriseId(), 2, roleName);
                    if (existRole != null) {
                        Optional<Role> roleGroup = roleRepository.findById(existRole.getParentId());
                        if (roleGroup == null) {
                            return ResultBean.failedResultWithMsg("角色组信息不存在或已删除！");
                        }
                        roleName = roleGroup.get().getName();
                    }
                    args.add("%" + roleName + "%");
                }
                sql += "  ORDER BY `property_type` DESC ";
                List<RoleVO> query = jdbcTemplate.query(sql, args.toArray(), new RoleRowMapper());
                LOG.info(sql + args);
                result.setResultData(query);
            } else {
                if (StringUtils.isBlank(roleName)) {
                    List<Role> roleList = roleRepository.findAllByOrgIdAndPropertyAndPropertyType(tokenRedisVo.getEnterpriseId(), 1,0);
                    result.setResultData(roleList);
                } else {
                    Role existRole = roleRepository.findByOrgIdAndPropertyAndName(tokenRedisVo.getEnterpriseId(), 2, roleName);
                    if (existRole != null) {
                        Long parentId = existRole.getParentId();
                        Optional<Role> roleGroup = roleRepository.findById(parentId);
                        result.setResultData(roleGroup);
                    } else {
                        Role role = roleRepository.findAllByOrgIdAndPropertyAndNameOrderByPropertyTypeDesc(tokenRedisVo.getEnterpriseId(), 1, roleName);
                        List<Role> query = new ArrayList<>();
                        if (ObjectUtil.isNotEmpty(role)) {
                            query.add(role);
                        }
                        result.setResultData(query);
                    }
                }
            }
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

//    /*
//    *查询用户所具有权限的角色树形结构
//     */
//   public ResultBean<Object> userRoleTree(String accessToken, String roleName) {
//        LOG.info("RolesService userRoleTree accessToken={},roleName={}", accessToken, roleName);
//        ResultBean<Object> result = new ResultBean<>();
//        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
//        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
//        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
//        try {
//            if (tokenRedisVo == null) {
//                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
//                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
//                return result;
//            }
//            User user = userRepository.findById(tokenRedisVo.getId());
//            if (user == null) {
//                return ResultBean.failedResultWithMsg("用户信息不存在或已删除！");
//            }
//            Optional<Department> existDepartment = departmentRepository.findById(tokenRedisVo.getEnterpriseId());
//            if (existDepartment == null) {
//                return ResultBean.failedResultWithMsg("企业信息不存在或已删除！");
//            }
//            if (tokenRedisVo.getMasterStatus() != 1) {
//                roleRepository.findByOrgId(tokenRedisVo.getEnterpriseId());
//            } else {
//                if (StringUtils.isBlank(roleName)) {
//                    List<Role> roleList = roleRepository.findAllByOrgIdAndPropertyOrderByPropertyTypeDesc(tokenRedisVo.getEnterpriseId(), 1);
//                    result.setResultData(roleList);
//                } else {
//                    Role existRole = roleRepository.findByOrgIdAndPropertyAndName(tokenRedisVo.getEnterpriseId(), 2, roleName);
//                    if (existRole != null) {
//                        Long parentId = existRole.getParentId();
//                        Optional<Role> roleGroup = roleRepository.findById(parentId);
//                        result.setResultData(roleGroup);
//                    } else {
//                        Role role = roleRepository.findAllByOrgIdAndPropertyAndNameOrderByPropertyTypeDesc(tokenRedisVo.getEnterpriseId(), 1, roleName);
//                        List<Role> query = new ArrayList<>();
//                        query.add(role);
//                        result.setResultData(query);
//                    }
//                }
//            }
//        } catch (Exception e) {
//            LOG.error(e.getMessage(), e);
//            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
//            result.setMsg(e.getMessage());
//        }
//        return result;
//    }

    /*
     *显示当前角色下的用户成员
     */
    /*public ResultBean<Object> rolePeopleList(String accessToken, Long roleId) {
        LOG.info("RolesService rolePeopleList accessToken={},roleId={}", accessToken, roleId);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);

        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (roleId == null) {
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                return result;
            }
            Optional<Role> existRole = roleRepository.findById(roleId);
            if (existRole == null) {
                return ResultBean.failedResultWithMsg("角色信息不存在或已删除！");
            }
            String sql = "SELECT u.`id`,d.`name` AS depName,u.`name`,u.job_number AS jobNumber FROM saas_user_role_ref ur \n" +
                    "INNER JOIN `saas_user` u ON ur.user_id = u.id INNER JOIN `saas_user_department_ref` df ON u.id = df.user_id \n" +
                    "INNER JOIN `saas_department` d ON df.`dep_id`= d.id WHERE df.type = 1 AND ur.role_id = ?";
            List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql, roleId);
            result.setResultData(mapList);

        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }*/

    public ResultBean<List<RolePeopleVO>> rolePeopleList(String accessToken, Long roleId) {
        try {
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }

            if (roleId == null) {
                return ResultBean.failedResultOfParamWithMsg("角色id为空");
            }

            String sql = "SELECT distinct u.`id`,u.`name`\n" +
                    "FROM saas_user_role_ref ur \n" +
                    "INNER JOIN `saas_user` u ON ur.user_id = u.id \n" +
                    "where ur.role_id = ? and u.status != 2";
            List<RolePeopleVO> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(RolePeopleVO.class), roleId);
            if (list.isEmpty()) {
                return ResultBean.successfulResult(list);
            }

            List<String> userIds = list.stream().distinct().map(RolePeopleVO::getId).collect(Collectors.toList());
            String sql2 = "SELECT r.user_id userId,r.dep_id depId,d.`name` depName\n" +
                    "FROM saas_user_department_ref r\n" +
                    "JOIN `saas_department` d ON r.`dep_id`= d.id \n" +
                    "WHERE r.user_id IN " + SqlUtils.foreachIn(userIds.size());
            Map<String, List<Map<String, Object>>> map = jdbcTemplate.queryForList(sql2, userIds.toArray()).stream().
                    collect(Collectors.groupingBy(c -> c.get("userId").toString()));

            if (!map.isEmpty()) {
                for (RolePeopleVO vo : list) {
                    List<Map<String, Object>> li = map.get(vo.getId());
                    if (!li.isEmpty()) {
                        vo.setDepIds(li.stream().map(c -> Long.parseLong(c.get("depId").toString())).distinct().collect(Collectors.toList()));
                        vo.setDepNames(li.stream().map(c -> c.get("depName").toString()).distinct().collect(Collectors.toList()));
                    }
                }
            }

            return ResultBean.successfulResult(list);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    /*
     *新增角色下成员
     */
    public ResultBean<Object> addRolePeople(String accessToken, List<UserRoleRefVO> userRoleRefVOList) {
        LOG.info("RolesService rolePeopleList accessToken={},userRoleRefVOList={}", accessToken, userRoleRefVOList);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (userRoleRefVOList == null) {
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                return result;
            }

            //删除角色已选成员
            if (!userRoleRefVOList.isEmpty()) {
                Long roleId = userRoleRefVOList.get(0).getRoleId();
                List<Map<String, Object>> list = roleAddedPeople(accessToken, roleId).getResultData();
                if (!list.isEmpty()) {
                    List<String> userIds = new ArrayList<>();
                    for (Map<String, Object> map : list) {
                        userIds.add(map.get("id").toString());
                    }

                    List<Object> args = new ArrayList<>();
                    args.add(roleId);
                    args.addAll(userIds);
                    jdbcTemplate.update("DELETE FROM saas_user_role_ref WHERE role_id = ? AND user_id IN " + SqlUtils.foreachIn(userIds.size()),
                            args.toArray());
                }
            }

            for (UserRoleRefVO userRoleRefVO : userRoleRefVOList) {
                CheckUtil checkUtil = new CheckUtil();
                checkUtil.checkValues(userRoleRefVO);
                if (checkUtil.isNull()) {
                    continue;
                }
                Optional<Role> existRole = roleRepository.findById(userRoleRefVO.getRoleId());
                if (existRole == null) {
                    continue;
                }
                User existUser = userRepository.findById(userRoleRefVO.getUserId());
                if (existUser == null) {
                    continue;
                }
                UserRoleRef existUserRole = userRoleRefRepository.findByUserIdAndRoleId(userRoleRefVO.getUserId(), userRoleRefVO.getRoleId());
                if (existUserRole != null) {
                    userRoleRefVO.setId(existUserRole.getId());
                }
                UserRoleRef userRoleRef = new UserRoleRef();
                BeanUtils.copyProperties(userRoleRefVO, userRoleRef);
                userRoleRefRepository.save(userRoleRef);
            }
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     *删除角色下的成员
     */
    public ResultBean<Object> deleteRolePeople(String accessToken, List<UserRoleRefVO> userRoleRefVOList) {
        LOG.info("RolesService deleteRolePeople accessToken={},userRoleRefVOList={}", accessToken, userRoleRefVOList);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (userRoleRefVOList == null) {
                result.setCode(StatusCode.ERROR_CODE_10005.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_10005.getErrorMsg());
                return result;
            }
            for (UserRoleRefVO userRoleRefVO : userRoleRefVOList) {
                CheckUtil checkUtil = new CheckUtil();
                checkUtil.checkValues(userRoleRefVO);
                if (checkUtil.isNull()) {
                    continue;
                }
                Optional<Role> existRole = roleRepository.findById(userRoleRefVO.getRoleId());
                if (existRole == null) {
                    continue;
                }
                User existUser = userRepository.findById(userRoleRefVO.getUserId());
                if (existUser == null) {
                    continue;
                }
                Role role = roleRepository.findById(userRoleRefVO.getRoleId()).get();
                if (role.getType() != 1) {
                    userRoleRefRepository.deleteByUserIdAndRoleId(userRoleRefVO.getUserId(), role.getParentId());
                    userRoleRefRepository.deleteByUserIdAndRoleId(userRoleRefVO.getUserId(), userRoleRefVO.getRoleId());
                }
            }
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    public ResultBean<Object> userPermissionDepartmentPeople(String accessToken, Long roleId, String name, String mobile) {
        LOG.info("RolesService userPermissionDepartmentPeople accessToken={},roleId={},name={}", accessToken, roleId, name);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }

            User existUser = userRepository.findById(tokenRedisVo.getId());
            if (existUser == null) {
                return ResultBean.failedResultWithMsg("用户信息不存在或已删除！");
            }

            StringBuffer childDepIds = new StringBuffer();
            /*String departmentSql = " SELECT dep_id FROM saas_user_department_ref WHERE user_id = ?";
            List<Long> ids = jdbcTemplate.queryForList(departmentSql, new Object[]{tokenRedisVo.getId()}, Long.class);*/

            //企业下所有部门
            List<Long> depIds = new ArrayList<>();
            depIds = this.allChild(tokenRedisVo.getEnterpriseId());
            depIds.add(tokenRedisVo.getEnterpriseId());

            for (Long id : depIds) {
                childDepIds.append(id).append(",");
            }

            String childDepId = childDepIds.substring(0, childDepIds.lastIndexOf(","));

            String sql = "SELECT DISTINCT u.`id`,u.`name` FROM saas_user u INNER JOIN `saas_user_department_ref` d ON u.id = d.user_id WHERE u.`status`!= 2";

            List<Object> args = new ArrayList<>();
            sql += " AND d.`dep_id` IN (" + childDepId + ")";

            /*if (roleId != null) {
                sql += "   AND u.id NOT IN (SELECT user_id FROM `saas_user_role_ref` WHERE role_id = ? )";
                args.add(roleId);
            }*/

            if (!StringUtils.isBlank(name)) {
                sql += "   AND NAME  LIKE ? ";
                args.add("%" + name + "%");
            }
            if (!StringUtils.isBlank(mobile)) {
                sql += "   AND mobile  LIKE ? ";
                args.add("%" + mobile + "%");
            }

            List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql, args.toArray());
            result.setResultData(mapList);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    public ResultBean<List<Map<String, Object>>> roleAddedPeople(String accessToken, Long roleId) {
        LOG.info("RolesService roleAddedPeople accessToken={},roleId={}", accessToken, roleId);
        ResultBean<List<Map<String, Object>>> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }

            User existUser = userRepository.findById(tokenRedisVo.getId());
            if (existUser == null) {
                return ResultBean.failedResultWithMsg("用户信息不存在或已删除！");
            }

            StringBuffer childDepIds = new StringBuffer();

            //企业下所有部门
            List<Long> depIds = new ArrayList<>();
            depIds = this.allChild(tokenRedisVo.getEnterpriseId());
            depIds.add(tokenRedisVo.getEnterpriseId());

            for (Long id : depIds) {
                childDepIds.append(id).append(",");
            }

            String childDepId = childDepIds.substring(0, childDepIds.lastIndexOf(","));

            String sql = "SELECT DISTINCT u.`id`,u.`name` FROM saas_user u INNER JOIN `saas_user_department_ref` d ON u.id = d.user_id WHERE u.`status`!= 2";

            List<Object> args = new ArrayList<>();
            sql += " AND d.`dep_id` IN (" + childDepId + ")";

            sql += " AND u.id IN (SELECT user_id FROM `saas_user_role_ref` WHERE role_id = ? )";
            args.add(roleId);

            List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql, args.toArray());
            result.setResultData(mapList);

        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     *根据用户拥有的权限部门的其他人员
     */
    public ResultBean<Object> userPermissionDepartmentPeople2(String accessToken, Long roleId, String name, String mobile) {
        LOG.info("RolesService userPermissionDepartmentPeople accessToken={},roleId={},name={}", accessToken, roleId, name);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }

            User existUser = userRepository.findById(tokenRedisVo.getId());
            if (existUser == null) {
                return ResultBean.failedResultWithMsg("用户信息不存在或已删除！");
            }

            StringBuffer childDepIds = new StringBuffer();
            /*String departmentSql = " SELECT dep_id FROM saas_user_department_ref WHERE user_id = ?";
            List<Long> ids = jdbcTemplate.queryForList(departmentSql, new Object[]{tokenRedisVo.getId()}, Long.class);*/

            //企业下所有部门
            List<Long> depIds = new ArrayList<>();
            depIds = this.allChild(tokenRedisVo.getEnterpriseId());
            depIds.add(tokenRedisVo.getEnterpriseId());

            for (Long id : depIds) {
                childDepIds.append(id).append(",");
            }

            String childDepId = "";
            if (StringUtils.isNotBlank(childDepIds)) {
                childDepId = childDepIds.substring(0, childDepIds.lastIndexOf(","));
            }

            String sql = "SELECT DISTINCT u.`id`,u.`name` FROM saas_user u INNER JOIN `saas_user_department_ref` d ON u.id = d.user_id WHERE u.`status`!= 2";

            List<Object> args = new ArrayList<>();
            if (!StringUtils.isBlank(childDepId)) {
                sql += "  AND d.`dep_id` IN  (" + childDepId + ")  ";
            }
            if (roleId != null) {
                sql += "   AND u.id NOT IN (SELECT user_id FROM `saas_user_role_ref` WHERE role_id = ? )";
                args.add(roleId);
            }
            if (!StringUtils.isBlank(name)) {
                sql += "   AND NAME  LIKE ? ";
                args.add("%" + name + "%");
            }
            if (!StringUtils.isBlank(mobile)) {
                sql += "   AND mobile  LIKE ? ";
                args.add("%" + mobile + "%");
            }

            List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql, args.toArray());
            result.setResultData(mapList);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }


    //查找当前部门节点所有节点(不包含当前节点)saas_department
    public List<Long> allChild(Long depId) {
        String sql = " select id from ( select t1.id,if(find_in_set(parent_id, @pids) > 0,@pids := concat(@pids, ',', id),0) as ischild from ( select id,parent_id from `saas_department` t order by parent_id, id ) t1,(select @pids := ?) t2 ) t3 where ischild != 0 \n";
        return jdbcTemplate.queryForList(sql, new Object[]{depId}, Long.class);
    }

    /*
     *修改角色权限
     */
    public ResultBean<Object> changeRolePermission(String accessToken, ParamVO paramVO) {
        LOG.info("RolesService changeRolePermission accessToken={},paramVO={}", accessToken, paramVO);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }
            if (paramVO == null) {
                result.setCode(StatusCode.ERROR_CODE_10004.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_10004.getErrorMsg());
                return result;
            }
            if (paramVO.getRoleId() == null) {
                result.setCode(StatusCode.ERROR_CODE_10004.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_10004.getErrorMsg());
                return result;
            }
            if (paramVO.getLongIds() == null && paramVO.getLongIds().size() == 0) {
                result.setCode(StatusCode.ERROR_CODE_10004.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_10004.getErrorMsg());
                return result;
            }
            Long roleId = paramVO.getRoleId();
            List<Long> permissionIds = paramVO.getLongIds();
            Optional<Role> existRole = roleRepository.findById(roleId);
            if (existRole == null) {
                return ResultBean.failedResultWithMsg("角色信息不存在或已删除！");
            }
            rolePermissionRepository.deleteAllByRoleId(roleId);
            for (Long permissionId : permissionIds) {
                Optional<Permission> existPermission = permissionRepository.findById(permissionId);
                if (existPermission != null) {
                    RolePermission rolePermission = new RolePermission();
                    rolePermission.setRoleId(roleId);
                    rolePermission.setPermissionId(permissionId);
                    rolePermissionRepository.save(rolePermission);
                }
            }
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /*
     *显示当前用户具有权限的角色组其他角色
     */
    public ResultBean<Object> presentUserRoleGroupOtherRole(@RequestHeader String accessToken) {
        LOG.info("RolesService presentUserRoleGroupOtherRole accessToken={}", accessToken);
        ResultBean<Object> result = new ResultBean<>();
        result.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());
        result.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        try {
            if (tokenRedisVo == null) {
                result.setCode(StatusCode.ERROR_CODE_40001.getErrorCode());
                result.setMsg(StatusCode.ERROR_CODE_40001.getErrorMsg());
                return result;
            }

            User existUser = userRepository.findById(tokenRedisVo.getId());
            if (existUser == null) {
                return ResultBean.failedResultWithMsg("用户信息不存在或已删除！");
            }

            String sql = "SELECT DISTINCT r.`id`,r.`name`,r.`type` FROM `saas_user_role_ref` ur \n" +
                    "INNER JOIN saas_role r ON ur.`role_id`= r.`id` WHERE ur.`user_id`= ? AND r.`property`=2";
            List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql, tokenRedisVo.getId());
            /*StringBuffer parentIds = new StringBuffer();
            maps.forEach(m -> {
                parentIds.append(m.get("parent_id")).append(",");
            });

            String parentId = parentIds.toString();
            if (!StringUtils.isBlank(parentId)) {
                parentId = parentId.substring(0, parentId.lastIndexOf(","));
            }

            StringBuffer sbSql = new StringBuffer(" SELECT DISTINCT r.`id`,r.`name`,r.`type` FROM `saas_user_role_ref` ur INNER JOIN saas_role r  ON   ur.`role_id`=r.`id`  WHERE 1=1 ");
            if (!StringUtils.isBlank(parentId)) {
                sbSql.append("  AND r.`parent_id` IN (" + parentId + ") ");
            }
            List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sbSql.toString());*/

            result.setResultData(maps);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            result.setMsg(e.getMessage());
        }
        return result;
    }

    /**
     * 获取普通用户默认角色
     *
     * @return
     * @author shun
     * @date 2021年5月15日
     */
    public Long getDefaultUserRoleId() {
        Role role = roleRepository.findByCodeAndOrgId(Constant.APP_REGISTERED_ROLE_CODE, Long.valueOf(-1));
        if (role == null) {
            return null;
        } else {
            return role.getId();
        }
    }

    /**
     * 获取单位承租人角色
     *
     * @return
     * @author xin
     * @date 2022年5月18日
     */
    public Long getCommonRoleDeptRoleId() {
        Role role = roleRepository.findByCodeAndOrgId(Constant.APP_COMMON_ROLE_DEPT, Long.valueOf(-1));
        if (role == null) {
            return null;
        } else {
            return role.getId();
        }
    }


    /**
     * APP-个人承租人角色
     *
     * @return
     * @author xin
     * @date 2022年5月18日
     */
    public Long getCommonRoleOneRoleId() {
        Role role = roleRepository.findByCodeAndOrgId(Constant.APP_COMMON_ROLE_ONE, Long.valueOf(-1));
        if (role == null) {
            return null;
        } else {
            return role.getId();
        }
    }



    public ResultBean<Object> deleteRole(String accessToken, Long roleId) {
        try {
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }

            if (roleId == null) {
                return ResultBean.failedResultOfParamWithMsg("角色id为空");
            }

            String sql = "SELECT distinct count(1) \n" +
                    "FROM saas_user_role_ref ur \n" +
                    "INNER JOIN `saas_user` u ON ur.user_id = u.id \n" +
                    "where ur.role_id = ? and u.status != 2 and u.type != 1";
            Long count = jdbcTemplate.queryForObject(sql, Long.class, roleId);
            if (count > 0L) {
                return ResultBean.failedResultWithMsg("角色存在成员，无法删除");
            }

            roleRepository.deleteById(roleId);

            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<Object> deleteRoleGroup(String accessToken, Long roleGroupId) {
        try {
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }

            if (roleGroupId == null) {
                return ResultBean.failedResultOfParamWithMsg("角色组id为空");
            }

            List<Role> roles = roleRepository.findByParentId(roleGroupId);
            if (!roles.isEmpty()) {
                return ResultBean.failedResultWithMsg("角色组存在角色，无法删除");
            }

            roleRepository.deleteById(roleGroupId);

            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }


}
